#include "ADUMainScene.h"

USING_NS_CC;

Scene* MainLayer::createScene() {
	// 'scene' is an autorelease object
	auto scene = Scene::create();

	// 'layer' is an autorelease object
	auto layer = MainLayer::create();

	// add layer as a child to scene
	scene->addChild(layer);

	// return the scene
	return scene;
}

// on "init" you need to initialize your instance
bool MainLayer::init() {
	//////////////////////////////
	// 1. super init first
	if (!Layer::init()) {
		return false;
	}

	CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic(MUSIC_BG, true);

	Size visibleSize = Director::getInstance()->getVisibleSize();
	Vec2 origin 	 = Director::getInstance()->getVisibleOrigin();

	initParameters();
	_radius = visibleSize.width / 6;

	// Add Title Game
	_titleGame = Text::create("ulTra dueT", "fonts/game_title.ttf", 150.0f);
	_titleGame->setPosition(Vec2(_centerX, origin.y + visibleSize.height - 100.0f));
	_titleGame->setColor(Color3B(255,255,255));
	this->addChild(_titleGame, Z_TEXT);

	// Add Go Text
	_goText = Text::create("GO", "fonts/game_title.ttf", 70.0f);
	_goText->setPosition(_posGo);
	_goText->setColor(Color3B(255,255,255));
	this->addChild(_goText, Z_TEXT);

	// Add Score Text
    _scoreText = Text::create("", "fonts/game_font.TTF", 60.0f);
	_scoreText->setPosition(_posScore);
	_scoreText->setColor(Color3B(255,255,0));
	this->addChild(_scoreText, Z_TEXT);

	// Add best score when gameover
	_scoreGameOver = Text::create("", "fonts/game_font.TTF", 50.0f);
	_scoreGameOver->setPosition(_posDraft);
	_scoreGameOver->setColor(Color3B(255,255,255));
	this->addChild(_scoreGameOver, Z_TEXT);

	_bestScoreGameOver = Text::create("", "fonts/game_font.TTF", 50.0f);
	_bestScoreGameOver->setPosition(_posDraft);
	_bestScoreGameOver->setColor(Color3B(255,255,255));
	this->addChild(_bestScoreGameOver, Z_TEXT);

	// Add stars
    createStars();

	// Add circle fire & water

//	createGalaxy();
	_circleFire = Sprite::create("fire.png");
	_circleFire->setPosition(Vec2(_centerX + _radius * cos(_angle),
								  _centerY + _radius * sin(_angle)));

	_circleWater = Sprite::create("fire.png");
	_circleWater->setPosition(Vec2(_centerX - _radius * cos(_angle),
			              		   _centerY - _radius * sin(_angle)));

	this->addChild(_circleFire);
	this->addChild(_circleWater);

	createParticleFire(_circleFire->getPositionX(),_circleFire->getPositionY());
	createParticleWater(_circleWater->getPositionX(),_circleWater->getPositionY());
	drawCircle();
	this->setTouchEnabled(true);

	// Add a brick
	createBricks();

	// Handle Touch Event
	_listener = EventListenerTouchOneByOne::create();
	_listener->onTouchBegan 	= CC_CALLBACK_2(MainLayer::onTouchBegan, this);
	_listener->onTouchMoved 	= CC_CALLBACK_2(MainLayer::onTouchMoved, this);
	_listener->onTouchEnded 	= CC_CALLBACK_2(MainLayer::onTouchEnded, this);
	_listener->onTouchCancelled = CC_CALLBACK_2(MainLayer::onTouchCancelled,this);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(_listener, this);

	// Call update function
	this->scheduleUpdate();
	return true;
}

void MainLayer::update(float dt) {
	// Update score
	if(_startGame == true) {
		sprintf(_score, "%d", GameManager::getInstance()->getScore());
		_scoreText->setText(_score);
	}
    

	// Update brick
	Vec2 firePos 	= _circleFire->getPosition();
	Vec2 waterPos 	= _circleWater->getPosition();
	for (int i = 0; i < NUM_BRICK && (_startGame == true); i++) {
		_brick[i]->update(dt);
		if(_brick[i]->getBoundingBox().containsPoint(firePos)) {
		 	createExplodingRing(firePos);
			showGameOver();
		} else if(_brick[i]->getBoundingBox().containsPoint(waterPos)) {
		 	createExplodingRing(waterPos);
			showGameOver();
		 }		 
	}

	// Update particle position
	setEmitterPosition(_emitterFire, 
					   _circleFire->getPositionX(),
					   _circleFire->getPositionY());
	
	setEmitterPosition(_emitterWater, 
					   _circleWater->getPositionX(),
		    		   _circleWater->getPositionY());
	
	if (_move == false && _startGame == true)
		return;
	
	_angle += _speedRotate * _direction * dt;
	float x = _radius * cos(_angle);
	float y = _radius * sin(_angle);
	_circleFire->setPosition(Vec2(_centerX + x, _centerY + y));
	_circleWater->setPosition(Vec2(_centerX - x, _centerY - y));
}

bool MainLayer::onTouchBegan(Touch* touch, Event* event) {
	//if (_move == true)
	//	return true;
	Vec2 touchLocation = touch->getLocation();
	if(!_startGame && abs(touchLocation.x - _centerX) < _radius && abs(touchLocation.y - _centerY) < _radius) {
		_startGame = true;
		if(_restartGame) {
			GameManager::getInstance()->resetScore();
			showBrick();
			_restartGame = false;
			_scoreText->setPosition(_posScore);
			hideObject(_scoreGameOver);
			hideObject(_bestScoreGameOver);
			hideObject(_goText);
		} else {
			hideObject(_goText);
			hideObject(_titleGame);			
		}
	}
	if(_startGame) {
		if (touchLocation.x < _centerX) {
			_direction = 1;
		} else {
			_direction = -1;
		}
		_move = true;
	}
	
	return true;
}

void MainLayer::onTouchMoved(Touch* touch, Event* event) {

}

void MainLayer::onTouchEnded(Touch* touch, Event* event) {
	if (_move)
		_move = false;
}

void MainLayer::onTouchCancelled(Touch* touch, Event* event) {

}

void MainLayer::initParameters() {
	Size visibleSize = Director::getInstance()->getVisibleSize();
	Vec2 origin = Director::getInstance()->getVisibleOrigin();

	_centerX = origin.x + visibleSize.width / 2;
	_centerY = origin.y + visibleSize.height / 2;
	
	_startGame 	 = false;
	_angle 		 = 0;
	_direction 	 = 1;
	_speedRotate = 5.0f;
	_gravity 	 = 50.0f;
	_move 		 = false;
	_restartGame = false;
	_posGo 		 			= Vec2(_centerX, _centerY);
	_posScore 	 			= Vec2(origin.x + visibleSize.width/8, origin.y + visibleSize.height - 50.0f);
	_posScoreGameOver 		= Vec2(_centerX, origin.y + visibleSize.height - 50.0f);
	_posBestScoreGameOver 	= Vec2(_centerX, origin.y + visibleSize.height - 100.0f);
	_posDraft 				= Vec2(10*_centerX, _centerY);
	
}

void MainLayer::createParticleFire(float x, float y) {
	_emitterFire = ParticleSun::create();
	_emitterFire->retain();
	this->addChild(_emitterFire, 10);

	_emitterFire->setTexture(Director::getInstance()->getTextureCache()->addImage("fire.png"));
	setEmitterPosition(_emitterFire, x, y);
}
void MainLayer::createParticleWater(float x, float y) {
	_emitterWater = ParticleSun::create();
	_emitterWater->setStartColor(Color4F(0.12f, 0.25f, 0.76f, 1.0f));
	_emitterWater->retain();
	this->addChild(_emitterWater, 10);

	_emitterWater->setTexture(Director::getInstance()->getTextureCache()->addImage("fire.png"));
	setEmitterPosition(_emitterWater, x, y);

}

void MainLayer::setEmitterPosition(ParticleSystemQuad* particle, float x,
		float y) {
	if (particle) {
		particle->setPosition(x, y);
	}
}

void MainLayer::drawCircle() {
	_draw = DrawNode::create();

	std::vector<Vec2> vertex;
	float precision = 0.01f;
	float cir = 2 * M_PI;
	for (float a = 0.0f; a < cir; a += precision) {
		float x = _centerX + _radius * cos(a);
		float y = _centerY + _radius * sin(a);
		vertex.push_back(Vec2(x, y));
	}
	_draw->drawPolygon(&vertex[0], vertex.size(), ccc4f(0, 0, 0, 0), 0.7f,
			ccc4f(1, 1, 1, 0.7));

	this->addChild(_draw, 100);
}

void MainLayer::createBricks() {

	float deltaY 	= _radius * 2;
	float baseY 	= Director::getInstance()->getVisibleSize().height;
    float totalHeight = NUM_BRICK * deltaY;
	auto s = Director::getInstance()->getWinSize();
	for (int i = 0; i < NUM_BRICK; i++) {
		float brickX;
		float brickY;
		_brick[i] = BrickSprite::create(rand() % BRICK_TYPE_MAX);
		_brick[i]->setSpeed(DEFAULT_SPEED);
		if (_brick[i]->getAction())
			_brick[i]->runAction(RepeatForever::create(_brick[i]->getAction()));
        if(_brick[i]->getType() == BRICK_TYPE_1 || _brick[i]->getType() == BRICK_TYPE_5) {
            brickX = s.width / 2;
        } else {
            brickX = (rand()%2 == 1) ? (s.width / 4) : (3 * s.width / 4);
        }
		
		brickY = baseY + (i + 1) * deltaY;
		_brick[i]->setPosition(Vec2(brickX, brickY));
		_brick[i]->setPosStart(Vec2(brickX, brickY));
        _brick[i]->setTotalHeight(totalHeight);
		this->addChild(_brick[i]);
	}
}

void MainLayer::createStars() {
    Size visibleSize = Director::getInstance()->getVisibleSize();
	Vec2 origin 	 = Director::getInstance()->getVisibleOrigin();
    _emitterStar 	 = ParticleRain::create();
    _emitterStar->retain();
    this->addChild(_emitterStar, 0);
    
    auto p = _emitterStar->getPosition();
    _emitterStar->setPosition( Vec2( p.x, p.y-100) );
    _emitterStar->setLife(6);
    _emitterStar->setTexture( Director::getInstance()->getTextureCache()->addImage("fire.png") );
    
    setEmitterPosition(_emitterStar,_centerX,visibleSize.height);

}

void MainLayer::createExplodingRing(const Vec2& pos) {
	std::string filename = "Particles/ExplodingRing.plist";
    _emitterRing= ParticleSystemQuad::create(filename);
    _emitterRing->retain();
    this->addChild(_emitterRing, 10);

    setEmitterPosition(_emitterRing,pos.x, pos.y);
}


void MainLayer::createGalaxy() {
	_emitterGalaxy= ParticleGalaxy::create();
    _emitterGalaxy->retain();
    this->addChild(_emitterGalaxy, 10);

    _emitterGalaxy->setTexture( Director::getInstance()->getTextureCache()->addImage("fire.png") );

    setEmitterPosition(_emitterGalaxy, _centerX, _centerY);
}


void MainLayer::showGameOver() {
	_startGame 	 = false;
	_restartGame = true;
	_move 		 = true;
	hideBrick();
	hideObject(_scoreText);
	_scoreGameOver->setPosition(_posScoreGameOver);
	_bestScoreGameOver->setPosition(_posBestScoreGameOver);	
	_goText->setPosition(_posGo);
/*
	memset(_scoreTextGO, 0,5);
	sprintf(_scoreTextGO, "MARK %d", GameManager::getInstance()->getScore());
	memset(_bestScoreTextGO, 0,5);
    sprintf(_bestScoreTextGO, "BEST %d", GameManager::getInstance()->getBestScore());
	_scoreGameOver->setText(_scoreTextGO);
	_bestScoreGameOver->setText(_bestScoreTextGO);
	*/
}

void MainLayer::hideObject(Node * node) {
	node->setPosition(_posDraft);
}


void MainLayer::hideBrick() {
	for (int i = 0; i < NUM_BRICK; i++) {
		if(_brick[i] != NULL)
			hideObject(_brick[i]);
	}	
}

void MainLayer::showBrick() {
	for (int i = 0; i < NUM_BRICK; i++) {
		if(_brick[i] != NULL)
			_brick[i]->resetPosition();
	}	
}